/**
 *  可下钻的表格 2021-3-22 wl
 * @params {object} dataSource 数据源，包括 result ，columns
 *  {Array} columns-item 只有dId和text字段，可以手动添加 两个扩展属性 props 和 customRender
 *  {object} props 包含antd原生的columns属性 如列的宽度
 *  customRender 自定义渲染内容
 * @params {object} tableProps 原生antd table属性
 * @params {Funtion} onClickLabel 点击每一个value的回调
 * @params {Funtion} onUdateData 下钻回调
 */

import React, {useState, useEffect} from 'react';
import {Table, Button} from 'antd';
import {PlusSquareOutlined, MinusSquareOutlined} from '@ant-design/icons';

import './index.less';

const propStr = 'Prop';

const TableConfig = props => {
    const {dataSource, onUdateData, onClickLabel, tableProps} = props;
    const [data, setData] = useState([]);
    const [columns, setColumns] = useState([]);

    // 递归函数 把所有的合并的列平铺，整理成table-datasource的格式
    const que = (item, rowData, data, numObj, columns) => {
        const {config: {rank}, count, dId, text, values, depth} = item;

        // 如果需要固定列，根据数据动态添加的排名列， 不会固定。所以不动态处理该列，手动传入所有的列配置
        // 排名列赋值
        if (rank) {
            const keys = Object.keys(rank) || [];
            keys.forEach(key => {
                rowData = {
                    [`${key}${propStr}`]: {
                        ...item,
                        config: {},
                        // 排名不合并行
                        endMergeIdx: numObj.num + count,
                    },
                    ...rowData,
                    children: null,
                    [key]: rank[key]
                };

                // if (columns[depth - 1]?.dId !== key) {
                //     // 在当前列前插入排名的列 包含dId 和 text
                //     const addCol = {
                //         dId: key,
                //         text: key
                //     };
                //     columns.splice(depth - 1, 0, addCol);
                // }
            });
        }

        if (item.children) {
            item.children.forEach(child => {
                rowData = {
                    [`${dId}${propStr}`]: {
                        ...item,
                        endMergeIdx: numObj.num + count,
                    },
                    ...rowData,
                    children: null,
                    [dId]: text
                };

                que(child, rowData, data, numObj, columns);
            });
        }
        else {
            rowData = {
                [`${dId}${propStr}`]: {...item},
                ...rowData,
                children: null,
                [dId]: text
            };
            values.forEach(col => {
                rowData[col.dId] = col.text;
            });

            numObj.num = numObj.num + 1;
            data.push(rowData);
        }
    };

    // 获取数据
    const getData = (children, columns) => {
        const data = [];
        const numObj = {num: 0};
        children.forEach(item => {
            const rowData = {};
            que(item, rowData, data, numObj, columns);
        });

        return data;
    };

    // 展开行
    const handleOpen = (record, index, column, values, dId) => props => {
        const formatCurCol = {
            dimensionId: dId,
            dimensionName: column,
            value: record[column]
        };

        onUdateData && onUdateData({formatCurCol, record, index, column, values, handleType: 'open'});
    };

    // 关闭某行
    const handleClose = (record, index, column, values, dId) => props => {
        const originColumns = dataSource?.columns;
        // 操作列的深度 相当于第n列
        const curDep = record[`${column}${propStr}`]?.depth;
        // 收起来的数组：包含当前列的所有父节点
        const drilingList = [];

        // 递归取前一列节点
        let prevDep = curDep - drilingList.length - 1;
        while (prevDep > 0 && drilingList.length < curDep) {
            for (const prop in record) {
                if (record[prop]?.depth === prevDep) {
                    const dimensionName = record[prop].dId;
                    const value = record[prop].text;
                    const dimensionId = originColumns.find(item => item.text === dimensionName)?.dId;
                    const formatPrevCol = {
                        dimensionId,
                        dimensionName,
                        value
                    };

                    drilingList.push(formatPrevCol);
                    prevDep = curDep - drilingList.length - 1;
                }
            }
        }

        const formatCurCol = {
            dimensionId: dId,
            dimensionName: column,
            value: record[column]
        };
        drilingList.push(formatCurCol);

        onUdateData && onUdateData({drilingList, formatCurCol, record, index, column, values, handleType: 'close'});
    };

    // 列
    const getColumns = (originColumns, data) => originColumns.map(item => ({
        width: 100,
        title: item.title || item.text,
        dataIndex: item.text,
        ...(item.props || {}),
        render(value, record, index) {
            const originProp = record?.[`${item.text}${propStr}`] || {};
            const {config, count, endMergeIdx} = originProp;
            const {status} = config || {};
            const renderValue = onClickLabel
                ? (
                    <Button type="link" onClick={onClickLabel}>
                        {item.customRender && item.customRender(value) || value}
                    </Button>
                ) : (
                    item.customRender && item.customRender(value) || value
                );

            // 收起状态 展示展开按钮
            if (status === 1) {
                return (
                    <span onClick={handleOpen(record, index, item.text, data, item.dId)}>
                        <PlusSquareOutlined className="func" />
                        {renderValue}
                    </span>
                );
            }

            // 展开状态 展示收起按钮
            if (status === 2 || item.text.indexOf('rank') > -1) {
                const obj = {
                    children: status === 2 ? (
                        <span onClick={handleClose(record, index, item.text, data, item.dId)}>
                            <MinusSquareOutlined className="func" />
                            {renderValue}
                        </span>
                    ) : (
                        <span>
                            {renderValue}
                        </span>
                    ),
                    props: {},
                };

                // 从当前位置合并
                if (index === endMergeIdx - count) {
                    obj.props.rowSpan = count;
                }
                else if (index <= endMergeIdx) {
                    obj.props.rowSpan = 0;
                }

                return obj;
            }

            return renderValue;
        },
    }));

    useEffect(() => {
        const result = dataSource?.result || [];
        const columns = dataSource?.columns || [];
        const children = result?.children;

        // 循环取数据
        if (children) {
            const data = getData(children, columns);
            const newColumns = getColumns(columns, data);

            setData(data);
            setColumns(newColumns);
        }

    }, [dataSource]);

    return (
        <Table
            dataSource={data}
            columns={columns}
            pagination={false}
            scroll={{y: 300}}
            bordered
            size="small"
            {...tableProps}
        />
    );
};

export default TableConfig;
